package com.ltmonitor.web.controller;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.ltmonitor.entity.*;
import com.ltmonitor.service.*;
import com.ltmonitor.video.entity.VideoServerConfig;
import com.ltmonitor.web.constants.FunctionConstant;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.ltmonitor.util.Constants;
import com.ltmonitor.util.StringUtil;
import com.ltmonitor.web.util.JsonMessage;
import com.ltmonitor.web.util.OnlineUser;
/**
 * 基类
 * 主要提供了Session存取在线用户的方法
 * @author admin
 *
 */
import com.sun.tools.extcheck.Main;
public class GenericAction {
	public static final String ONLINE_USER = "onlineUser";

	private static final String JSON_FORWARD = "jsonSuccess";

	protected Logger log = Logger.getLogger(getClass());
	@Autowired
	protected IBasicDataService basicDataService;

	@Autowired
	protected HttpServletRequest request;
	
	/**
	 * session key， 用于存放用户在界面上车辆树种多选的车辆Id
	 */
	protected static String REGISTER_VEHICLEID_KEY = "registerVehicleIds";

	/**
	 * 存放当前在线用户信息的key
	 */
	protected static String ONLINE_USER_KEY = "currUserInfo";

	/**
	 * 存放授权部门Id map的可以
	 */
	protected static String SESSION_KEY_DEP = "session_key_department";
	/**
	 * session中存放地图工具栏权限菜单的key
	 */
	protected static String SESSION_MAP_TOOL_MENU = "MapToolMenu";

	/**
	 * session中存放地图工具栏权限菜单的key
	 */
	protected static String SESSION_WEB_FUNC = "WebFunc";

	/**
	 * session中存放命令工具栏权限菜单的key
	 */
	protected static String SESSION_COMMAND_TOOL_MENU = "CommandToolMenu";

	/**
	 * session中存放命令车辆树右键菜单的key
	 */
	protected static String SESSION_RIGHT_MENU = "RightMenu";

	/**
	 * session中存放快捷菜单的key
	 */
	protected static String SESSION_SHORT_CUT_MENU = "ShortCutMenu";
	/**
	 * session中存放主菜单的key
	 */
	protected static String SESSION_MAIN_MENU = "MainMenu";

	/**
	 * 保存平台参数配置的Session的key
	 */
	protected static String SESSION_KEY_SYSTEM_CONFIG = "systemConfig";
	/**
	 * 保存用户选项的key
	 */
	protected static String SESSION_KEY_USER_PREFERENCE = "userPreference";
	/**
	 * 保存OSD配置的key
	 */
	protected static String SESSION_VEHICLE_OSD = "vehicleOsd";
	// 用户的权限以map的形式存放，便于查看是否有某一个权限
	protected static String SESSION_KEY_FUNCTION_MAP = "userFuncMap";

	/**
	 * 假删除调转名称
	 */
	protected static final String FAKE_DELETED = "fakeDeleted";

	protected static final String DELETED = "deleted";

	protected static final String VIEW = "view";

	protected static final String SAVE_SUCCESS = "save";

	protected static final String CREATE = "create";

	protected static final String LIST_ALL = "listAll";

	protected static final String LIST = "list";

	@Autowired
	protected IDepartmentService departmentService;
	@Autowired
	protected IOperationLogService operationLogService;

	@Autowired
	protected IQueryService queryService;

	@Autowired
	protected IVehicleDataService vehicleDataService;

	/**
	 * 获取车辆图标
	 */
	@Autowired
	private IVehicleStateIconConfigService vehicleStateIconConfigService;

	/**
	 * 供弹出提示窗口页面用,retMethod为关闭弹出窗口时 要刷新主窗口页面所调用的主页面的script函数名
	 */
	private String retMethod;


	@Autowired
	protected IVideoServerConfigService videoServerConfigService;
	protected VideoServerConfig getVideoServerConfig() {
		return this.videoServerConfigService.getVideoServerConfig();
	}
	/**
	 * 获得Request的参数数据 之所以是Public方法，是为了单元测试时，可以直接拿到Map并注入模拟数据
	 * 
	 * @return
	 */
	public Map getParams() {
		Map parameters = request.getParameterMap();
		Map paraMap = new HashMap();
		for (Object key : parameters.keySet()) {
			String strKey = "" + key;
			int index = strKey.indexOf("[]");
			if (index > 0) {
				strKey = strKey.replaceAll("\\[\\]", "");
			}
			String[] values = (String[]) parameters.get(key);
			if (values.length == 1) {
				String strValue = values[0];
				if (strValue != null && strValue.isEmpty() == false)
					paraMap.put(strKey, strValue);
			} else
				paraMap.put(strKey, values);
		}
		return paraMap;
	}

	/**
	 * 基础数据转换，将数据表中标志字段转换为文字描述
	 * 
	 * @param rowData
	 * @param field
	 * @param parentCode
	 * @return
	 */
	protected String convert(Map rowData, String field, String parentCode) {
		String fieldValue = "" + rowData.get(field);
		BasicData bd = getBasicDataService().getBasicDataByCode(fieldValue,
				parentCode);
		if (bd != null) {
			rowData.put(field, bd.getName());
			return bd.getName();
		}
		return "";
	}

	protected String convert(String fieldValue, String parentCode) {
		BasicData bd = getBasicDataService().getBasicDataByCode(fieldValue,
				parentCode);
		if (bd != null) {
			return bd.getName();
		}
		return fieldValue;
	}

	protected String getMapType() {
		OnlineUser user = this.getOnlineUser();
		if (user != null) {
			String mapType = user.getMapType();
			if (StringUtil.isNullOrEmpty(mapType)) {
				mapType = this.getSystemConfig().getMapType();
			}
			return mapType;
		}
		return Constants.MAP_BAIDU;
	}

	/**
	 * 用户是否有某个功能的权限
	 * 
	 * @param funcName
	 * @return
	 */
	protected boolean isAuthorized(String funcName) {
		OnlineUser user = this.getOnlineUser();
		if(user == null)
			return false;
		
		return user.isAuthorized(funcName);
	}

	/**
	 * 是否有实时视频监控的权限
	 * @return
	 */
	protected  boolean hasRealTimeVideoAuthority()
	{
		return isAuthorized(FunctionConstant.FUNC_REALTIME_VIDEO);
	}

	/**
	 * 是否有视频回放的权限
	 * @return
	 */
	protected  boolean hasPlaybackVideoAuthority()
	{
		return isAuthorized(FunctionConstant.FUNC_PLAYBACK_VIDEO);
	}

	/**
	 * 是否有报警联动监控的权限
	 * @return
	 */
	protected  boolean hasVideoWithAlarmAuthority()
	{
		return isAuthorized(FunctionConstant.FUNC_VIDEO_WITH_ALARM);
	}

	protected void setAuthorizedDep(UserInfo user) {
		OnlineUser onlineUser = this.getOnlineUser();
		if (user == null || onlineUser == null)
			return;
		Set<Department> depSet = user.getDepartments();
		if (user.isSuperAdmin()
				&& depSet.isEmpty()) {
			// 如果是超级用户，将加所有权限,可以分配所有管理部门
			Collection<Department> allDepList = this.departmentService
					.loadAll();
			for (Department dep : allDepList) {
				onlineUser.getDepIdList().add(dep.getEntityId());
			}
		} else {
			for (Department dep : depSet) {
				if (dep.getDeleted() == false) {
					onlineUser.getDepIdList().add(dep.getEntityId());
				}
			}
		}

	}

	/**
	 * 清除Session
	 */
	protected void clearSession() {

		request.getSession().invalidate();
		;
	}

	/**
	 * 应当对此方法进行限制使用
	 * 
	 * @return
	 */
	protected HttpSession getSession() {
		return request.getSession();

	}

	protected void putSession(String key, Object value) {
		getSession().setAttribute(key, value);
	}

	protected Object getFromSession(String key) {
		return getSession().getAttribute(key);
	}

	// Json跳转
	protected JsonMessage json(boolean success, Object data) {
		return new JsonMessage(success, data);
	}

	// Json跳转
	protected JsonMessage json(boolean success, String msg) {
		return (new JsonMessage(success, msg));
	}


	public static JsonMessage jsonSuccess(String msg) {
		return new JsonMessage(true, msg);
	}

	public static JsonMessage jsonFail(String msg) {
		return new JsonMessage(false, msg);
	}

	public static ModelAndView forwardWithMsg(String path, String msg) {
		ModelAndView m = new ModelAndView(path);
		m.addObject("message", msg);
		return m;
	}



	public String getRetMethod() {
		return retMethod;
	}

	public void setRetMethod(String retMethod) {
		this.retMethod = retMethod;
	}



	/**
	 * 每个用户会分配经过授权的车组,判断车组是否是用户的权限中所辖部门.
	 * 
	 * @param depId
	 * @return
	 */
	protected boolean isAuthorizedDep(int depId) {
		Map<Integer, Integer> depIdMap = (Map<Integer, Integer>) this
				.getFromSession(SESSION_KEY_DEP);
		return depIdMap != null && depIdMap.containsKey(depId);
	}

	protected List<Long> getAuthorizedDepIdList() {
		return this.getOnlineUser().getDepIdList();
	}

	/**
	 * 记录用户的操作日志
	 * 
	 * @param detail
	 *            操作内容描述
	 */
	public void LogOperation(String detail) {
		try {
			OnlineUser u = this.getOnlineUser();
			if (u != null) {
				OperationLog log = new OperationLog();
				log.setUserId(u.getEntityId());
				log.setUserName(u.getName());
				log.setDetail(detail);
				log.setCompanyId(u.getCompanyId());
				HttpServletRequest r = this.getRequest();
				String uri = r.getRequestURI();
				log.setUrl(uri);
				String Agent = r.getHeader("User-Agent");

				log.setIp(r.getRemoteAddr() + "[" + Agent + "]");
				operationLogService.saveOrUpdate(log);
			}
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	public OnlineUser getOnlineUser() {
		OnlineUser userInfo = (OnlineUser) getFromSession(ONLINE_USER_KEY);
		
		//HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();  

		return userInfo;
	}

	public UserPreference getUserPreference()
	{
		UserPreference p = (UserPreference)getFromSession(SESSION_KEY_USER_PREFERENCE);
		return p;
	}

	public SystemConfig getSystemConfig() {
		SystemConfig config = (SystemConfig) getFromSession(SESSION_KEY_SYSTEM_CONFIG);
		if (config == null)
			return new SystemConfig();
		return config;
	}


	protected String getMapIcon(VehicleData vd, GPSRealData rd) {
		String vehicleStatus = "offline-normal";
		//String vehicleType = vd.getVehicleType();
		String status = rd.getStatus();
		String acc = status.substring(31, 32);
		if (rd != null && rd.getOnline()) {
			/*if (rd.getAlarmState() != null
					&& rd.getAlarmState().indexOf("1") >= 0) {
				vehicleStatus = "alarm";
			} else {
				vehicleStatus = rd.getVelocity() > 0 ? "run" : "parking";
			}*/
			int angle = rd.getDirection();
			if(acc.equals("1")){
				if(rd.getAlarmState() != null && rd.getAlarmState().indexOf("1") >= 0){
					if(rd.getVelocity() > 0){
						if (angle > 345 || angle <= 15){
						    //return "0.png";
						    vehicleStatus = "drive-alarm-0";
						}  
						if (angle > 15 && angle <= 45){
							//return "30.png";
							vehicleStatus = "drive-alarm-30";
						}
						if (angle > 45 && angle <= 75){
							//return "30.png";
							vehicleStatus = "drive-alarm-60";
						}
						if (angle >75 && angle <= 105){
						    //return "90.png";
							vehicleStatus = "drive-alarm-90";
						}
						if (angle > 105 && angle <= 135){
							//return "120.png";
							vehicleStatus = "drive-alarm-120";
						}
						if (angle > 135 && angle <= 165){
							//return "120.png";
							vehicleStatus = "drive-alarm-150";
						}
						if (angle >165 && angle <= 195){
						   // return "180.png";
						    vehicleStatus = "drive-alarm-180";
						} 
						if (angle > 195 && angle <= 225){
							//return "210.png";
							vehicleStatus = "drive-alarm-210";
						}
						if (angle > 225 && angle <= 255){
							//return "210.png";
							vehicleStatus = "drive-alarm-240";
						}
						if (angle >255 && angle <= 285){
						    //return "270.png";
						    vehicleStatus = "drive-alarm-270";
						} 	
						if (angle > 285 && angle <= 315){
							//return "300.png";
							vehicleStatus = "drive-alarm-300";
						}
						if (angle > 315 && angle <= 345){
							//return "300.png";
							vehicleStatus = "drive-alarm-330";
						}
						//vehicleStatus = "drive-alarm";
					}else{
						vehicleStatus = "speed0-alarm";
					}			
				}else{
					if(rd.getVelocity() > 0){
						//vehicleStatus = "drive-normal";
						if (angle > 345 || angle <= 15){
						    //return "0.png";
						    vehicleStatus = "drive-normal-0";
						}  
						if (angle > 15 && angle <= 45){
							//return "30.png";
							vehicleStatus = "drive-normal-30";
						}
						if (angle > 45 && angle <= 75){
							//return "30.png";
							vehicleStatus = "drive-normal-60";
						}
						if (angle >75 && angle <= 105){
						    //return "90.png";
							vehicleStatus = "drive-normal-90";
						}
						if (angle > 105 && angle <= 135){
							//return "120.png";
							vehicleStatus = "drive-normal-120";
						}
						if (angle > 135 && angle <= 165){
							//return "120.png";
							vehicleStatus = "drive-normal-150";
						}
						if (angle >165 && angle <= 195){
						   // return "180.png";
						    vehicleStatus = "drive-normal-180";
						} 
						if (angle > 195 && angle <= 225){
							//return "210.png";
							vehicleStatus = "drive-normal-210";
						}
						if (angle > 225 && angle <= 255){
							//return "210.png";
							vehicleStatus = "drive-normal-240";
						}
						if (angle >255 && angle <= 285){
						    //return "270.png";
						    vehicleStatus = "drive-normal-270";
						} 	
						if (angle > 285 && angle <= 315){
							//return "300.png";
							vehicleStatus = "drive-normal-300";
						}
						if (angle > 315 && angle <= 345){
							//return "300.png";
							vehicleStatus = "drive-normal-330";
						}
					}else{
						vehicleStatus = "speed0-normal";
					}	
				}
			}else{
				if(rd.getAlarmState() != null && rd.getAlarmState().indexOf("1") >= 0){
					vehicleStatus = "accoff-alarm";			
				}else{
					vehicleStatus = "accoff-normal";	
				}	
			}
			if(!(rd.IsValid())){
				vehicleStatus = "gpsinvalid-normal";
			}
			
		}

		//String hql = "from VehicleStateIcon where vehicleType = ? and vehicleStatus = ?";
		//VehicleStateIcon stateIcon = (VehicleStateIcon) this.vehicleStateIconConfigService
		//		.find(hql, new Object[] { vehicleType, vehicleStatus });
		//if (stateIcon == null) {
		String hql = "from VehicleStateIcon where defaultVehicleType = ? and vehicleStatus = ?";
		VehicleStateIcon stateIcon = (VehicleStateIcon) this.vehicleStateIconConfigService.find(hql,
					new Object[] { true, vehicleStatus });
		//}
		if (stateIcon == null)
			return "";
		return stateIcon.getIcon();
	}


	public void setOnlineUser(OnlineUser onlineUser) {
		this.putSession(ONLINE_USER_KEY, onlineUser);
	}


	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}


	public IBasicDataService getBasicDataService() {
		return basicDataService;
	}

	public void setBasicDataService(IBasicDataService basicDataService) {
		this.basicDataService = basicDataService;
	}

	public IDepartmentService getDepartmentService() {
		return departmentService;
	}

	public void setDepartmentService(IDepartmentService departmentService) {
		this.departmentService = departmentService;
	}
	

}
